package fct.mpc.utils;

import java.io.BufferedWriter;
import java.io.InputStream;
import java.util.ArrayList;

import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;

import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;
import org.xmlpull.v1.XmlPullParser;
import org.xmlpull.v1.XmlPullParserFactory;

public class SnipeCollection
{
	protected static ArrayList<Snipe> snipes = new ArrayList<Snipe>();
	
	public static void addSnipe(String name, String type, int level, int health, int attack, int defense, boolean caught)
	{
		snipes.add(new Snipe(name, type, level, health, attack, defense, caught));
	}
	
	public static void clearCollection()
	{
		snipes.clear();
	}
	
	public static boolean hasSnipes()
	{
		return !snipes.isEmpty();
	}
	
	public static ArrayList<Snipe> getAllSnipes()
	{
		return snipes;
	}
	
	public static ArrayList<Snipe> getAvailableSnipes()
	{
		ArrayList<Snipe> available = new ArrayList<Snipe>();
		
		for(int i=0; i<snipes.size(); i++)
		{
			if(snipes.get(i).caught)
				available.add(snipes.get(i));
		}
		
		return available;
	}
	
	public static Snipe getSnipe(String name)
	{
		for(Snipe snipe : snipes)
		{
			if(snipe.getName().equalsIgnoreCase(name))
				return snipe;
		}
		
		return null;
	}

	public static void populateSnipeCollectionByAsset(InputStream inputStream)
	{
		DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
			
		try
		{
			DocumentBuilder builder = factory.newDocumentBuilder();
			Document dom = builder.parse(inputStream);

			Element root = dom.getDocumentElement();
			NodeList items = root.getElementsByTagName("snipe");
			
			for (int i=0; i<items.getLength(); i++)
			{
				String snipeName = "";
				String snipeType = "";
				int snipeLevel = 0;
				int snipeHealth = 0;
				int snipeAttack = 0;
				int snipeDefense = 0;
				boolean snipeCaught = false;
				
				Node item = items.item(i);
				NodeList properties = item.getChildNodes();
		
				for(int j=0; j<properties.getLength(); j++)
				{
					Node property = properties.item(j);
					String name = property.getNodeName();
						
					if (name.equalsIgnoreCase("name"))
						snipeName = property.getFirstChild().getNodeValue();
					else if (name.equalsIgnoreCase("element"))
						snipeType = property.getFirstChild().getNodeValue();
					else if (name.equalsIgnoreCase("level"))
						snipeLevel = Integer.parseInt(property.getFirstChild().getNodeValue());
					else if (name.equalsIgnoreCase("health"))			                       
						snipeHealth = Integer.parseInt(property.getFirstChild().getNodeValue());
					else if (name.equalsIgnoreCase("attack"))
						snipeAttack = Integer.parseInt(property.getFirstChild().getNodeValue());
					else if (name.equalsIgnoreCase("defense"))			                       
						snipeDefense = Integer.parseInt(property.getFirstChild().getNodeValue());
					else if (name.equalsIgnoreCase("caught"))
						snipeCaught = Boolean.parseBoolean(property.getFirstChild().getNodeValue());
				}
					
				SnipeCollection.addSnipe(snipeName, snipeType, snipeLevel, snipeHealth, snipeAttack, snipeDefense, snipeCaught);
			}
		}
		catch (Exception e)
		{
			throw new RuntimeException(e);
		}	
	}
	
	public static void populateSnipeCollectionByXML(InputStream ins)
	{
		try
		{
			XmlPullParserFactory factory  = XmlPullParserFactory.newInstance();
			XmlPullParser parser = factory.newPullParser();
			
			parser.setInput(ins, null);
			
			int eventType = parser.getEventType();
			boolean done = false;
			
			String snipeName = "";
			String snipeType = "";
			int snipeLevel = 0;
			int snipeHealth = 0;
			int snipeAttack = 0;
			int snipeDefense = 0;
			boolean snipeCaught = false;
		
			while (eventType != XmlPullParser.END_DOCUMENT && !done)
			{
				String name = null;
				
				switch (eventType)
				{
				case XmlPullParser.START_DOCUMENT:               
					break;           
				case XmlPullParser.START_TAG:
					name = parser.getName();
					
					if (name.equalsIgnoreCase("name"))
						snipeName = parser.nextText();
					else if (name.equalsIgnoreCase("element"))
						snipeType = parser.nextText();
					else if (name.equalsIgnoreCase("level"))
						snipeLevel = Integer.parseInt(parser.nextText());
					else if (name.equalsIgnoreCase("health"))			                       
						snipeHealth = Integer.parseInt(parser.nextText());
					else if (name.equalsIgnoreCase("attack"))
						snipeAttack = Integer.parseInt(parser.nextText());
					else if (name.equalsIgnoreCase("defense"))			                       
						snipeDefense = Integer.parseInt(parser.nextText());
					else if (name.equalsIgnoreCase("caught"))
						snipeCaught = Boolean.parseBoolean(parser.nextText());         
					break;
				case XmlPullParser.END_TAG:       
					name = parser.getName();
					
					if (name.equalsIgnoreCase("snipe"))
						SnipeCollection.addSnipe(snipeName, snipeType, snipeLevel, snipeHealth, snipeAttack, snipeDefense, snipeCaught);
					else if (name.equalsIgnoreCase("snipes"))
						done = true;
					break;        
				} 
			
				eventType = parser.next();
			}
		}
		catch (Exception e)
		{
			throw new RuntimeException(e);
		}
	}
	
	public static void writeSnipeCollectionAsXML(BufferedWriter bw)
	{
		try
		{
			bw.write("<snipes>\n");
			
			for(Snipe s : SnipeCollection.getAllSnipes())
				bw.write(s.getAsXML());
			
			bw.write("</snipes>");
			bw.flush();
			bw.close();
		}
		catch (Exception e)
		{
			throw new RuntimeException(e);
		}
		
		SnipeCollection.clearCollection();
	}
}